#include "Serveur.h"

Serveur::Serveur(int port)
{
    this->taille = sizeof(struct sockaddr_un);
    this->port = port;
    this->socketReception = initSocketServeur(port);
    pthread_mutex_init(&verrouListeClientsConnectes, NULL);
    pthread_mutex_init(&verrouListeSalles, NULL);
    pthread_mutex_init(&verrouListeActivites, NULL);

    // Construction du qcm.
    QuestionQCM questionQCM;
    string rep1;
    string rep2;
    string rep3;
    string rep4;
    questionQCM.question = "Quelle est la fonction permettant de créer un tableau ?";
    rep1 = "Un crayon et une rêgle";
    rep2 = "La balise <TABLE> </TABLE>";
    rep3 = "La balise <TABLEAU> </TABLEAU>";
    rep4 = "La balise <TAB> </TAB>";
    questionQCM.reponses.push_back(rep1);
    questionQCM.reponses.push_back(rep2);
    questionQCM.reponses.push_back(rep3);
    questionQCM.reponses.push_back(rep4);
    qcm.push_back(questionQCM);
    questionQCM.reponses.clear();
    questionQCM.question = "Quelle fonction permet de définir une \"case\" dans un tableau ?";
    rep1 = "Aucune";
    rep2 = "Insérer \"case\" dans l'assistant graphique";
    rep3 = "La balise <TR> </TR> ";
    rep4 = "La balise <TD> </TD> ";
    questionQCM.reponses.push_back(rep1);
    questionQCM.reponses.push_back(rep2);
    questionQCM.reponses.push_back(rep3);
    questionQCM.reponses.push_back(rep4);
    qcm.push_back(questionQCM);
    questionQCM.reponses.clear();
    questionQCM.question = "Comment insère-t-on un titre dans un tableau ?";
    rep1 = "Avec a balise <TITLE> </TITLE>";
    rep2 = "On écrit le titre directement dans le tableau";
    rep3 = "Avec la balise <CAPTION> </CAPTION>";
    rep4 = "Avec la balise <TH> </TH>";
    questionQCM.reponses.push_back(rep1);
    questionQCM.reponses.push_back(rep2);
    questionQCM.reponses.push_back(rep3);
    questionQCM.reponses.push_back(rep4);
    qcm.push_back(questionQCM);
    questionQCM.reponses.clear();
    questionQCM.question = "Comment met-on du texte en gras en langage HTML ?";
    rep1 = "Avec la balise <GRAS> </GRAS>";
    rep2 = "Avec la balise <B> </B>";
    rep3 = "Avec la balise <G> </G>";
    rep4 = "En appuyant sur l'icône G";
    questionQCM.reponses.push_back(rep1);
    questionQCM.reponses.push_back(rep2);
    questionQCM.reponses.push_back(rep3);
    questionQCM.reponses.push_back(rep4);
    qcm.push_back(questionQCM);
    questionQCM.reponses.clear();
}

Serveur::~Serveur()
{

}

bool Serveur::ajouterLogin(string login, SessionClientSurServeur *session)
{
    bool ajoute = false;
    if(login.size() > 0)
    {
        // lock mutex listeLogin
        map<string,SessionClientSurServeur*>::iterator it = listeClientsConnectes.find(login);
        if(it == listeClientsConnectes.end())
        {
            listeClientsConnectes[login] = session;
            ajoute = true;
        }
        else
        {
            ajoute = false;
        }
        // unlock mutex ListeLogin
    }
    return ajoute;

}

void Serveur::enleverLogin(string login)
{
    map<string,SessionClientSurServeur*>::iterator it = listeClientsConnectes.find(login);
    if(it != listeClientsConnectes.end()) listeClientsConnectes.erase(it);
}

bool Serveur::dispoSalle(string idSalle)
{
    list<string>::iterator it;
    it = listeSalles.begin();
    while(it != listeSalles.end())
    {
        if((*it) == idSalle) return true;
        it++;
    }
    return false;
}

SessionClientSurServeur* Serveur::getSessionClient(string login)
{
    return listeClientsConnectes[login];
}

list<string> Serveur::getListeSalles()
{
    // lock mutex listeSalles.
    listeSalles.sort();
    // unlock mutex listeSalles.
    return listeSalles;
}


list<string> Serveur::getListeActivites(string idSalle)
{
    // MUTEX
    list<string> listeTmp = listeActivite[idSalle];
    cout<<"nombre d'activités "<<listeTmp.size()<<"\n";
    // MUTEX
    return listeTmp;
}

list<string> Serveur::getListeObsDansSalle(string idSalle)
{
    return listeObsDansSalle[idSalle];
}

list<string> Serveur::getListeEtuDansSalle(string idSalle)
{
    return listeEtuDansSalle[idSalle];
}

void Serveur::lancerServeur()
{
    if(socketReception != -1)
    {
        while (1)
        {
            std::cout<<"attente de connexion\n";
            GereClient client;
            client.serveur = this;
            client.socket = accept(socketReception, (sockaddr*)&(client.addresse),(socklen_t *) &taille);
            std::cout<<"Un client tente de se connecter.\n";
            pthread_create(&client.thread, NULL, gereClient, (void *)&client);
            std::cout<<"un client s'est connecté.\n"<<std::endl;
        }
    }
    else std::cout<<"Impossible d'attendre une connexion client sur la socket de réception.\n";
}

bool Serveur::ajouterSalle(string idSalle){
    listeSalles.push_front(idSalle);

    return true;
}

bool Serveur::ajouterActivites(string IdSalle, list<string> listeAct){
    listeActivite[IdSalle] = listeAct;
    return true;
}

void Serveur::ajouterObsDansSalle(string idSalle, string idObs)
{
    pthread_mutex_lock(&verrouListeObsDansSalle); // lock MUTEX
    list<string> listeObs = listeObsDansSalle[idSalle];
    listeObs.push_back(idObs);
    listeObsDansSalle[idSalle] = listeObs;
    cout<<"ajouterObsDansSalle("<<idSalle<<", "<<idObs<<")\n";
    pthread_mutex_unlock(&verrouListeObsDansSalle); // unlock MUTEX
}

void Serveur::ajouterEtuDansSalle(string idSalle, string idEtu)
{
    pthread_mutex_lock(&verrouListeEtuDansSalle); // lock MUTEX
    list<string> listeEtu = listeEtuDansSalle[idSalle];
    listeEtu.push_back(idEtu);
    listeEtuDansSalle[idSalle] = listeEtu;
    cout<<"ajouterEtuDansSalle("<<idSalle<<", "<<idEtu<<")\n";
    pthread_mutex_unlock(&verrouListeEtuDansSalle); // lock MUTEX
}

void Serveur::enleverObsDansSalle(string idSalle, string idObs)
{
    pthread_mutex_lock(&verrouListeObsDansSalle); // lock MUTEX
    list<string> listeObs = listeObsDansSalle[idSalle];
    listeObs.remove(idObs);
    listeObsDansSalle[idSalle] = listeObs;
    cout<<"enleverObsDansSalle("<<idSalle<<", "<<idObs<<")\n";
    pthread_mutex_unlock(&verrouListeObsDansSalle); // unlock MUTEX
}

void Serveur::enleverEtuDansSalle(string idSalle, string idEtu)
{
    pthread_mutex_lock(&verrouListeEtuDansSalle); // lock MUTEX
    list<string> listeEtu = listeEtuDansSalle[idSalle];
    listeEtu.remove(idEtu);
    listeEtuDansSalle[idSalle] = listeEtu;
    cout<<"enleverEtuDansSalle("<<idSalle<<", "<<idEtu<<")\n";
    pthread_mutex_unlock(&verrouListeEtuDansSalle); // lock MUTEX
}

pthread_mutex_t *Serveur::getVerrouListeClientsConnectes()
{
    return &verrouListeClientsConnectes;
}

pthread_mutex_t *Serveur::getVerrouListeSalles()
{
    return &verrouListeSalles;
}

pthread_mutex_t *Serveur::getVerrouListeActivite()
{
    return &verrouListeActivites;
}

pthread_mutex_t *Serveur::getVerrouListeObsDansSalle()
{
    return &verrouListeObsDansSalle;
}

pthread_mutex_t *Serveur::getVerrouListeEtuDansSalle()
{
    return &verrouListeEtuDansSalle;
}
